# -*- coding: utf-8 -*-
"""操作日志查看工具 - 用于查看系统中记录的用户操作日志"""

import os
import sys
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTableWidget, QTableWidgetItem, 
                           QVBoxLayout, QWidget, QLabel, QDateEdit, QPushButton, 
                           QComboBox, QHBoxLayout, QHeaderView, QMessageBox, QGroupBox, 
                           QLineEdit)
from PyQt5.QtCore import Qt, QDate
from PyQt5.QtGui import QFont
from db_utils import DatabaseUtils


class LogViewer(QMainWindow):
    """操作日志查看器主窗口类"""
    
    def __init__(self):
        """初始化日志查看器"""
        super().__init__()
        
        # 设置窗口属性
        self.setWindowTitle("操作日志查看器")
        self.setGeometry(100, 100, 1200, 700)
        
        # 初始化UI
        self.init_ui()
        
        # 加载日志数据
        self.load_logs()
        
        # 窗口最大化显示
        self.showMaximized()
        
    def init_ui(self):
        """初始化用户界面"""
        # 创建中心部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 创建主布局
        main_layout = QVBoxLayout(central_widget)
        
        # 创建标题
        title_label = QLabel("系统操作日志查看")
        title_font = QFont()
        title_font.setPointSize(16)
        title_font.setBold(True)
        title_label.setFont(title_font)
        title_label.setAlignment(Qt.AlignCenter)
        main_layout.addWidget(title_label)
        
        # 创建筛选条件组
        filter_group = QGroupBox("筛选条件")
        filter_layout = QHBoxLayout()
        
        # 开始日期选择 - 确保标题与输入框间隔距离为2
        start_date_sub_layout = QHBoxLayout()
        self.start_date_edit = QDateEdit()
        self.start_date_edit.setCalendarPopup(True)
        self.start_date_edit.setDate(QDate.currentDate().addDays(-30))
        self.start_date_edit.dateChanged.connect(self.validate_dates)
        start_date_sub_layout.addWidget(QLabel("开始日期:"))
        start_date_sub_layout.setSpacing(2)  # 设置组件间隔为2
        start_date_sub_layout.addWidget(self.start_date_edit)
        filter_layout.addLayout(start_date_sub_layout)
        
        # 结束日期选择 - 确保标题与输入框间隔距离为2
        end_date_sub_layout = QHBoxLayout()
        self.end_date_edit = QDateEdit()
        self.end_date_edit.setCalendarPopup(True)
        self.end_date_edit.setDate(QDate.currentDate())
        self.end_date_edit.dateChanged.connect(self.validate_dates)
        end_date_sub_layout.addWidget(QLabel("结束日期:"))
        end_date_sub_layout.setSpacing(2)  # 设置组件间隔为2
        end_date_sub_layout.addWidget(self.end_date_edit)
        filter_layout.addLayout(end_date_sub_layout)
        
        # 操作模块筛选
        self.module_combo = QComboBox()
        self.module_combo.addItem("全部模块")
        self.module_combo.addItems(["合同管理", "租金管理", "用户认证", "基础数据管理"])
        filter_layout.addWidget(QLabel("操作模块:"))
        filter_layout.addWidget(self.module_combo)
        
        # 用户名筛选（下拉框形式）
        self.username_combo = QComboBox()
        self.username_combo.setEditable(True)  # 设置为可编辑，允许手动输入
        filter_layout.addWidget(QLabel("用户名:"))
        filter_layout.addWidget(self.username_combo)
        
        # 初始添加"全部用户"选项并加载用户列表
        self.username_combo.addItem("全部用户")
        self.load_username_list()
        
        # 操作内容筛选（文本框形式）
        self.content_edit = QLineEdit()
        self.content_edit.setPlaceholderText("输入操作内容关键字")
        filter_layout.addWidget(QLabel("操作内容:"))
        filter_layout.addWidget(self.content_edit)
        
        # 详细信息筛选（文本框形式）
        self.detail_edit = QLineEdit()
        self.detail_edit.setPlaceholderText("输入详细信息关键字")
        filter_layout.addWidget(QLabel("详细信息:"))
        filter_layout.addWidget(self.detail_edit)
        
        # 操作结果筛选
        self.result_combo = QComboBox()
        self.result_combo.addItem("全部结果")
        self.result_combo.addItems(["成功", "失败", "异常"])
        filter_layout.addWidget(QLabel("操作结果:"))
        filter_layout.addWidget(self.result_combo)
        
        # 搜索按钮
        search_btn = QPushButton("搜索")
        search_btn.clicked.connect(self.load_logs)
        filter_layout.addWidget(search_btn)
        
        # 重置按钮
        reset_btn = QPushButton("重置")
        reset_btn.clicked.connect(self.reset_filters)
        filter_layout.addWidget(reset_btn)
        
        # 清空日志按钮
        clear_logs_btn = QPushButton("清空日志")
        clear_logs_btn.clicked.connect(self.clear_logs)
        filter_layout.addWidget(clear_logs_btn)
        
        # 添加筛选布局到组
        filter_group.setLayout(filter_layout)
        main_layout.addWidget(filter_group)
        
        # 创建日志表格
        self.log_table = QTableWidget()
        self.log_table.setColumnCount(8)
        self.log_table.setHorizontalHeaderLabels([
            "日志时间", "用户ID", "用户名", "操作模块", "操作内容", "操作结果", "详细信息", "IP地址"
        ])
        
        # 设置表格列宽自适应
        header = self.log_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(6, QHeaderView.Stretch)
        header.setSectionResizeMode(7, QHeaderView.ResizeToContents)
        
        # 添加表格到主布局
        main_layout.addWidget(self.log_table)
        
    def reset_filters(self):
        """重置筛选条件"""
        self.start_date_edit.setDate(QDate.currentDate().addDays(-30))
        self.end_date_edit.setDate(QDate.currentDate())
        self.module_combo.setCurrentIndex(0)
        self.username_combo.setCurrentIndex(0)
        self.content_edit.clear()
        self.detail_edit.clear()
        self.result_combo.setCurrentIndex(0)
        self.load_logs()
        
    def load_username_list(self):
        """从数据库加载用户列表到用户名下拉框"""
        conn = self.get_db_connection()
        if conn:
            try:
                cursor = conn.cursor()
                cursor.execute("SELECT DISTINCT username FROM operation_logs WHERE username IS NOT NULL AND username != '' ORDER BY username")
                usernames = cursor.fetchall()
                
                # 清除现有项（保留"全部用户"）
                current_index = self.username_combo.currentIndex()
                self.username_combo.clear()
                self.username_combo.addItem("全部用户")
                
                # 添加用户名
                for username in usernames:
                    self.username_combo.addItem(username[0])
                
                # 恢复之前的选择（如果存在）
                if current_index < self.username_combo.count():
                    self.username_combo.setCurrentIndex(current_index)
                
            except Exception as e:
                from logger_module import log_error
                log_error(f"加载用户名列表失败: {str(e)}")
            finally:
                conn.close()
        
    def validate_dates(self):
        """验证日期范围的有效性"""
        start_date = self.start_date_edit.date()
        end_date = self.end_date_edit.date()
        
        if start_date > end_date:
            # 如果开始日期晚于结束日期，将结束日期调整为开始日期
            self.end_date_edit.setDate(start_date)
            QMessageBox.warning(self, "日期范围无效", "开始日期不能晚于结束日期\n已自动调整结束日期为开始日期")
        
    def get_db_connection(self):
        """获取数据库连接，确保operation_logs表存在"""
        try:
            conn = DatabaseUtils.get_connection()
            if conn:
                # 检查并创建operation_logs表（如果不存在）
                success = DatabaseUtils.ensure_operation_logs_table_exists(conn)
                if not success:
                    QMessageBox.warning(self, "数据库警告", "检查或创建操作日志表时出错")
            return conn
        except Exception as e:
            QMessageBox.critical(self, "数据库错误", f"连接数据库失败: {str(e)}")
            return None
    
    def clear_logs(self):
        """清空当前筛选条件下的日志记录"""
        # 显示确认对话框
        reply = QMessageBox.question(self, '确认清空', 
                                   '确定要清空当前筛选条件下的所有日志记录吗？此操作不可恢复！',
                                   QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            # 获取当前筛选条件
            start_date = self.start_date_edit.date().toString("yyyy-MM-dd")
            end_date = self.end_date_edit.date().toString("yyyy-MM-dd")
            module = self.module_combo.currentText()
            username = self.username_combo.currentText()
            content = self.content_edit.text().strip()
            detail = self.detail_edit.text().strip()
            result = self.result_combo.currentText()
            
            # 构建DELETE查询
            delete_query = "DELETE FROM operation_logs WHERE 1=1"
            params = []
            
            # 添加日期范围筛选
            delete_query += " AND log_time BETWEEN ? AND ?"
            params.append(f"{start_date} 00:00:00")
            params.append(f"{end_date} 23:59:59")
            
            # 添加模块筛选
            if module != "全部模块":
                delete_query += " AND operation_module = ?"
                params.append(module)
            
            # 添加用户名筛选
            if username != "全部用户" and username:
                delete_query += " AND username LIKE ?"
                params.append(f"%{username}%")
            
            # 添加操作内容筛选
            if content:
                delete_query += " AND operation_content LIKE ?"
                params.append(f"%{content}%")
            
            # 添加详细信息筛选
            if detail:
                delete_query += " AND detail LIKE ?"
                params.append(f"%{detail}%")
            
            # 添加结果筛选
            if result != "全部结果":
                delete_query += " AND operation_result = ?"
                params.append(result)
            
            # 执行删除操作
            conn = self.get_db_connection()
            if conn:
                try:
                    cursor = conn.cursor()
                    cursor.execute(delete_query, params)
                    deleted_count = cursor.rowcount
                    conn.commit()
                    
                    # 显示成功消息
                    QMessageBox.information(self, "操作成功", 
                                          f"成功清空{deleted_count}条日志记录")
                    
                    # 重新加载日志，显示剩余记录
                    self.load_logs()
                    
                except Exception as e:
                    conn.rollback()
                    QMessageBox.critical(self, "删除错误", 
                                      f"清空日志失败: {str(e)}")
                finally:
                    conn.close()
    
    def load_logs(self):
        """从数据库加载日志数据并显示在表格中"""
        # 清空表格
        self.log_table.setRowCount(0)
        
        # 获取筛选条件
        start_date = self.start_date_edit.date().toString("yyyy-MM-dd")
        end_date = self.end_date_edit.date().toString("yyyy-MM-dd")
        module = self.module_combo.currentText()
        username = self.username_combo.currentText()
        content = self.content_edit.text().strip()
        detail = self.detail_edit.text().strip()
        result = self.result_combo.currentText()
        
        # 构建SQL查询
        query = "SELECT log_time, user_id, username, operation_module, operation_content, operation_result, detail, ip_address FROM operation_logs WHERE 1=1"
        params = []
        
        # 添加日期范围筛选
        query += " AND log_time BETWEEN ? AND ?"
        params.append(f"{start_date} 00:00:00")
        params.append(f"{end_date} 23:59:59")
        
        # 添加模块筛选
        if module != "全部模块":
            query += " AND operation_module = ?"
            params.append(module)
        
        # 添加用户名筛选
        if username != "全部用户" and username:
            query += " AND username LIKE ?"
            params.append(f"%{username}%")
        
        # 添加操作内容筛选
        if content:
            query += " AND operation_content LIKE ?"
            params.append(f"%{content}%")
        
        # 添加详细信息筛选
        if detail:
            query += " AND detail LIKE ?"
            params.append(f"%{detail}%")
        
        # 添加结果筛选
        if result != "全部结果":
            query += " AND operation_result = ?"
            params.append(result)
        
        # 添加排序
        query += " ORDER BY log_time DESC"
        
        # 执行查询
        conn = self.get_db_connection()
        if conn:
            try:
                cursor = conn.cursor()
                cursor.execute(query, params)
                logs = cursor.fetchall()
                
                # 填充表格
                self.log_table.setRowCount(len(logs))
                for row_idx, log in enumerate(logs):
                    for col_idx, value in enumerate(log):
                        # 如果值为None，显示为空字符串
                        item_text = "" if value is None else str(value)
                        item = QTableWidgetItem(item_text)
                        
                        # 设置单元格文本换行
                        item.setTextAlignment(Qt.AlignTop | Qt.AlignLeft)
                        
                        # 设置结果列的文字颜色
                        if col_idx == 5:  # 操作结果列
                            if item_text == "成功":
                                item.setForeground(Qt.green)
                            elif item_text == "失败" or item_text == "异常":
                                item.setForeground(Qt.red)
                        
                        self.log_table.setItem(row_idx, col_idx, item)
                
            except Exception as e:
                QMessageBox.critical(self, "查询错误", f"查询日志失败: {str(e)}")
            finally:
                conn.close()


# 创建并运行应用
if __name__ == "__main__":
    app = QApplication(sys.argv)
    viewer = LogViewer()
    viewer.show()
    sys.exit(app.exec_())